package com.hengpeng.itfin.domain.imprest.alipay;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.itfin.domain.imprest.AbstractImprestProcessor;
import com.hengpeng.itfin.domain.imprest.alipay.util.RSASignature;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfinbase.constants.PaymentConstants;
import com.hengpeng.itfinbase.message.partner.NotifyRequestMsg;
import com.hengpeng.itfinbase.message.partner.NotifyResponseMsg;
import com.hengpeng.itfinbase.message.partner.PayRequestMsg;
import com.hengpeng.itfinbase.message.partner.PayResponseMsg;
import com.hengpeng.itfinbase.persist.Payment;
import com.hengpeng.itfinbase.persist.Payment.PayStatus;
import com.hengpeng.itfinbase.persist.PaymentProvider;

/**
 * <pre>
 * 支付宝-andriod支付网关
 * </pre>
 * @author shanguogang
 * @version 1.0, 2015-8-14
 */
public class AlipayAndriodImprestProcessor extends AbstractImprestProcessor
{

	private final static Log logger = LogFactory.getLog(AlipayAndriodImprestProcessor.class);

	private static final String ALIPAYANDRIOD_CONFIG_PUBLICKEYID = "publicKeyId";

	private String publicKeyId;

	public AlipayAndriodImprestProcessor(ServiceFactory serviceFactory, PaymentProvider provider)
	{
		super(serviceFactory, provider);
		publicKeyId = provider.getExtConfigs().get(ALIPAYANDRIOD_CONFIG_PUBLICKEYID);
	}

	@Override
	public void payRequest(PayRequestMsg request, PayResponseMsg response)
	{
		// TODO Auto-generated method stub
		response.setOrdId(request.getId());// 生成订单号
	}

	@Override
	public void payNotify(NotifyRequestMsg request, NotifyResponseMsg response)
	{
		Map<String, String> parameters = request.getParameter();

		StringBuffer verifyData = new StringBuffer();
		verifyData.append("notify_data=");
		verifyData.append(parameters.get("notify_data"));
		/**
		 * RSA验签
		 */
		boolean verified = verifyRSA(verifyData.toString(), parameters.get("sign"), publicKeyId);
		if (verified)
		{// 成功
			try
			{
				Document document = DocumentHelper.parseText(parameters.get("notify_data"));
				Element root = document.getRootElement();
				String trade_status = root.elementText("trade_status");
				String money = root.elementText("total_fee");
				String orderNo = root.elementText("out_trade_no");
				Double doubleMoney = Double.parseDouble(money) * 100;
				/**
				 * 交易成功 trade_status=TRADE_FINISHED (若高级即时到账则trade_status=TRADE_SUCCESS)
				 */
				if ("TRADE_FINISHED".equals(trade_status) || "TRADE_SUCCESS".equals(trade_status))
				{
					response.setProviderId(this.provider.getId());
					response.setOrdId(orderNo);
					response.setTransAmt(money);
					ServiceResult<Payment> result = serviceFactory.getPayService().dealPayResult(
							request.getProviderId(), orderNo, doubleMoney.longValue(), PayStatus.SUCCESS, "支付成功");
					if (!result.getIsSuccess())
					{
						logger.info("providerid{" + this.provider.getId() + "},本地处理失败!失败信息:" + result.getMessage());
						response.setRespCode(result.getCode());
						response.setRespDesc(result.getMessage());
					}
					else
					{
						response.setMerchantId(this.provider.getMerchantId());
						response.setTransAmt(money);
						response.setOrdId(orderNo);
					}
				}
				else
				{
					logger.info("充值失败,providerid{" + this.provider.getId() + "},订单号{"
							+ (orderNo == null ? "" : orderNo) + "},订单状态{" + (trade_status == null ? "" : trade_status)
							+ "}");
					response.setRespCode(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRCODE_OTHER);
					response.setRespDesc("充值失败！");
					ServiceResult<Payment> result = serviceFactory.getPayService().dealPayResult(
							response.getProviderId(), response.getOrdId(), doubleMoney.longValue(), PayStatus.FAILED,
							response.getRespDesc());
				}
			}
			catch (DocumentException e)
			{
				logger.info("充值回调发生异常!providerid{" + this.provider.getId() + "}, 异常信息:" + e.getMessage());
				e.printStackTrace();
				response.setRespCode(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRCODE_OTHER);
				response.setRespDesc("处理失败，若确认已付款，请联系客服冲正！");
			}
		}
		else
		{// 验签失败
			logger.info("providerid{" + this.provider.getId() + "},回调验签失败!");
			// 验签失败
			response.setRespCode(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRCODE_DIGESTERROR);
			response.setRespDesc(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRMSG_DIGESTERROR);
		}
	}

	/**
	 * RSA验签
	 * @param verifyData 待签名数据
	 * @param sign 支付宝返回的签名
	 * @param key 支付宝公钥
	 * @return
	 */
	private boolean verifyRSA(String verifyData, String sign, String publicKey)
	{
		try
		{
			return RSASignature.doCheck(verifyData, sign, publicKey, "UTF-8");
		}
		catch (Exception e)
		{
			logger.info("RSA待验签数据:" + verifyData + "支付宝返回的签名：" + sign);
			e.printStackTrace();
		}
		return false;
	}
}
